home *** CD-ROM | disk | FTP | other *** search
- #include <stddef.h>
- #include <stdlib.h>
- #include <tos.h>
- #include "mbuf.h"
-
- #define Supexec(x) (x())
-
- #define SYSBASE ((SYSHDR*)0x4f2L)
-
- static BASPAG **oldpd;
- long set_pd(void);
- long restore_pd(void);
-
- char *buf_create(size_t size)
- {
- register char *buf;
-
- if(size % BUFALIGN)
- size += BUFALIGN - (size % BUFALIGN);
- size += sizeof(mbuf *);
- set_pd();
- buf = Malloc(size);
- restore_pd();
-
- if(!buf) return(NULL);
-
- *(char **)buf = buf+sizeof(char *);
- (*(mbuf **)buf)->length = size - sizeof(mbuf);
- (*(mbuf **)buf)->blk = NULL;
- return(buf);
- }
-
-
- char *buf_alloc(char *buf,size_t size)
- {
- register mbuf *freeblk;
- register mbuf **p_freeblk;
- register long align;
-
-
- size += sizeof(size_t);
- align = size % BUFALIGN;
- if(align)
- size += BUFALIGN - align;
- size -= sizeof(size_t);
-
- p_freeblk = (mbuf **)buf;
- freeblk = *p_freeblk;
- while(freeblk && freeblk->length < size)
- {
- p_freeblk = &(freeblk->blk);
- freeblk = freeblk->blk;
- }
- if(!freeblk) return(NULL);
- if(size < freeblk->length)
- {
- *p_freeblk = (mbuf *)((char*)freeblk + size + sizeof(size_t));
- (*p_freeblk)->length = freeblk->length - size - sizeof(size_t);
- (*p_freeblk)->blk = freeblk->blk;
- freeblk->length = size;
- }
- else /* new block fits exactly */
- {
- *p_freeblk = freeblk->blk;
- }
- return((char *)&freeblk->blk);
- }
-
-
- int buf_free(char *buf,char *blk)
- {
- register mbuf *freeblk;
- register mbuf **p_freeblk;
- register mbuf *nextblk;
- mbuf *prevblk;
-
- freeblk = *(mbuf **)buf;
- p_freeblk = NULL;
- nextblk = (mbuf *)(blk + ((size_t *)blk)[-1]);
- prevblk = NULL;
- blk -= sizeof(size_t);
-
- while(freeblk && nextblk > freeblk)
- {
- if(freeblk == (mbuf *)blk) return(0);
- if(!prevblk)
- {
- p_freeblk = (mbuf **)buf;
- }
- else
- {
- p_freeblk = &((*p_freeblk)->blk);
- }
- prevblk = freeblk;
- freeblk = freeblk->blk;
- }
- if(nextblk == freeblk) /* connect trailing free block */
- {
- ((mbuf *)blk)->length += freeblk->length + sizeof(size_t);
- ((mbuf *)blk)->blk = freeblk->blk;
- }
- else /* create a hole */
- {
- /* keep length of block */
- ((mbuf *)blk)->blk = freeblk;
- }
- if(prevblk && (char *)prevblk+prevblk->length+sizeof(size_t) == blk)
- { /* connect leading free block */
- prevblk->blk = ((mbuf *)blk)->blk;
- prevblk->length += ((mbuf *)blk)->length + sizeof(size_t);
- }
- else
- {
- if(!p_freeblk)
- {
- *((mbuf **)buf) = (mbuf *)blk;
- }
- else
- {
- prevblk->blk = (mbuf *)blk;
- }
- }
- return(1);
- }
-
-
- long set_pd(void)
- {
- oldpd = SYSBASE->_run;
- SYSBASE->_run = &_BasPag;
- return 0;
- }
-
- long restore_pd(void)
- {
- SYSBASE->_run = oldpd;
- return 0;
- }
-
-
-
- char *getmem(register long size)
- {
- char *got;
-
- /* this relies on malloc taking size_t, and size_t being long, */
- /* or else not compiling with -mshort */
- Supexec(set_pd);
- got = (char *) malloc(size);
- Supexec(restore_pd);
- return got;
- }
-
-
- char *resizemem(register void *ptr,register long size)
- {
- char *got;
-
- got = (char *) realloc(ptr,size);
- return got;
- }
-
-
- void freemem( void *ptr)
- {
- Supexec(set_pd); /* set own pid */
- free(ptr);
- Supexec(restore_pd); /* restore previous pid */
- }
-